两个应用程序之间的通信,我们可以理解为进程之间的通信,而进程之间进行通信的前提是我们能够找到某个进程,因此,我们需要给进程添加唯一的标示,在本地进程通信中我们可以使用PID来标示一个进程,但PID只在本地唯一,网络中的多个计算机之间的进程标示并不能保证唯一性,冲突的几率很大。
这时候我们需要另辟蹊径,TCP/IP协议族已为我们解决了这个问题,IP层的IP地址可以标示主机,而TCP层协议和端口号可以标示某个主机的某个进程,于是我们采取IP地址+协议+端口号作为唯一标示的这种形式,来确定网络中的一个进程,从而进行进程之间的通讯,这种方式就是我们Socket使用的通讯方式。
在学习Socket通讯之前,首先需要了解网络通讯结构、TCP和UPD,以下是这这两个知识点的简要介绍。
OSI模型/七层模型
网络通信结构是有一套标准模型的,由国际标准化组织ISO提出,被称为OSI模型,又称为七层模型。它的层次划分如下:
数据单元 | 层 | 功能 | |
---|---|---|---|
主机层 | Data 数据 |
7-应用层 | 提供为应用软件而设的界面,以设置与另一应用软件之间的通信。例如: HTTP,HTTPS,FTP,TELNET,SSH,SMTP,POP3等。 |
6-表示层 | 把数据转换为能与接收者的系统格式兼容并适合传输的格式。 | ||
5-会话层 | 负责在数据传输中设置和维护电脑网络中两台电脑之间的通信连接。 | ||
Segments 数据段 |
4-传输层 | 把传输表头(TH)加至数据以形成数据包。传输表头包含了所使用的协议等发送信息。例如:传输控制协议义(TCP) 等。 | |
媒介层 | 网络分组 数据报文 |
3-网络层 | 决定数据的路径选择和转寄,将网络表头(NH)加至数据包,以形成分组。网络表头包含了网络数据。例如:互联网协议(IP) 等。 |
Bit/Frame 数据帧 |
2-数据链路层 | 负责网络寻址、错误侦测和改错。当表头和表尾被加至数据包时,会形成了帧。数据链表头(DLH)是包含了物理地址和错误侦测及改错的方法。数据链表尾(DLT)是一串指示数据包末端的字符串。例如以太网、无线局域网(Wi-Fi)和通用分组无线服务(GPRS)等。 | |
Bit 比特 |
1-物理层 | 在局部局域网上传送帧,它负责管理电脑通信设备和网络媒体之间的互通。包括了针脚、电压、线缆规范、集线器、中继器、网卡、主机适配器等。 |
七层模型中数据的传输过程如下:
层 | 主机A | 主机B |
---|---|---|
应用层 | 标记1,用的什么软件发送 | 用什么软件打开 |
表示层 | 标记2,是什么类型数据(文本,图片,声音) | 数据的类型 |
会话层 | 标记3,传输给谁? | 发给谁 |
传输层 | 标记4,同过怎么样的传输方式(协议,端口) | 用的什么协议发送给哪个端口 |
网络层 | 标记5,发给哪一个IP地址? | 是否是发送给此IP地址 |
数据链路层 | 标记6,找到IP对应的MAC地址 | 是否是发送给此MAC地址的帧 |
物理层 | 1010101010010101010 | 10100101010100101 |
TCP/IP模型/四层模型
而我们在开发中广泛应用的是四层模型,也就是TCP/IP参考模型,这四层分别是硬件层、网络层、传输层、应用层。以下是OSI模型和IP/TCP模型的层次对比:
OSI七层模型 | TCP/IP四层模型 | 对应网络协议 | 数据单元 |
---|---|---|---|
应用层 | 应用层 | FTP(文件传输协议) HTTP(超文本传输协议) DNS(域名服务器协议) SMTP(简单邮件传输协议) NFS(网络文件系统协议) |
数据 |
表示层 | |||
会话层 | |||
传输层 | 传输层 | TCP(控制传输协议) UDP(用户数据报协议) |
数据包 |
网络层 | 网络层 | IP(网际协议) ICMP(网际控制消息协议) ARP(地址解析协议) RARP(反向地址解析协议) |
数据帧 |
数据链路层 | 硬件层 | HDLC(高级链路控制协议) PPP(点对点协议) SLIP(串行线路接口协议) |
比特 |
物理层 |
TCP/IP协议被组织成四个概念层,其中有三层对应于ISO参考模型中的相应层。ICP/IP协议族并不包含物理层和数据链路层,因此它不能独立完成整个计算机网络系统的功能,必须与许多其他的协议协同工作。 TCP/IP分层模型的四个协议层分别完成以下的功能:
硬件层
硬件层与OSI参考模型中的物理层和数据链路层相对应。它负责监视数据在主机和网络之间的交换。事实上,TCP/IP本身并未定义该层的协议,而由参与互连的各网络使用自己的物理层和数据链路层协议,然后与TCP/IP的网络接入层进行连接。
TCP/IP参考模型只是要求能够提供给其上层-网络互连层一个访问接口,以便在其上传递IP分组。
网络层
网络层是整个TCP/IP协议栈的核心。对应于OSI七层参考模型的网络层。本层包含
- IP协议(Internet Protocol,网际协议)
- RIP协议(Routing Information Protocol,路由信息协议)
- ARP协议(Address Resolution Protocol,地址解析协议)
IP协议是网际互联层最重要的协议,它提供的是一个可靠、无连接的数据报传递服务。IP层接收由更低层(硬件层例如以太网设备驱动程序)发来的数据包,并把该数据包发送到更高层也就是传输层,例如TCP或UDP层;
相反,IP层也把从TCP或UDP层接收来的数据包传送到更低层。
IP数据包是不可靠的,因为IP并没有做任何事情来确认数据包是否按顺序发送的或者有没有被破坏,IP数据包中含有发送它的主机的地址(源地址)和接收它的主机的地址(目的地址)。高层的TCP和UDP服务在接收数据包时,通常假设包中的源地址是有效的。
ARP协议其基本功能为通过目标设备的IP地址,查询目标设备的MAC地址,以保证通信的顺利进行。它是IPv4中网络层必不可少的协议,不过在IPv6中已不再适用,并被邻居发现协议(NDP)所替代。
网络层负责数据的包装、寻址和路由。它的功能是把分组发往目标网络或主机。同时,为了尽快地发送分组,可能需要沿不同的路径同时进行分组传递。因此,分组到达的顺序和发送的顺序可能不同,这就需要上层必须对分组进行排序。
网络层定义了分组格式和协议,即IP协议,网络互连层除了需要完成路由的功能外,也可以完成将不同类型的网络(异构网)互连的任务。除此之外,网络互连层还需要完成拥塞控制的功能。
它同时还包含
- Internet控制消息协议(Internet Control Message Protocol,ICMP)
ICMP协议是网络协议族的核心协议之一。它用于TCP/IP网络中发送控制消息,提供可能发生在通信环境中的各种问题反馈,通过这些信息,令管理者可以对所发生的问题作出诊断,然后采取适当的措施解决。
ICMP依靠IP协议来完成它的任务,它是IP协议的主要部分。它与传输协议如TCP和UDP显著不同:它一般不用于在两点间传输数据,通常不由网络程序直接使用,除了ping和traceroute这两个特别的例子。 IPv4中的ICMP被称作ICMPv4,IPv6中的ICMP则被称作ICMPv6。
网络层协议管理离散的计算机间的数据传输,如IP协议为用户和远程计算机提供了信息包的传输方法,确保信息包能正确地到达目的机器。这一过程中,IP和其他网络层的协议共同用于数据传输,如果没有使用一些监视系统进程的工具,用户是看不到在系统里的IP的。
网络嗅探器Sniffers是能看到这些过程的一个装置(它可以是软件,也可以是硬件),它能读取通过网络发送的每一个包,即能读取发生在网络层协议的任何活动,因此网络嗅探器Sniffers会对安全造成威胁重要的网络层协议包括ARP、ICMP和IP协议等。
传输层
在TCP/IP模型中,传输层的功能是使源端主机和目标端主机上的对等实体可以进行会话。在传输层定义了两种服务质量不同的协议。
传输层对应于OSI参考模型的传输层,为应用层实体提供端到端的通信功能,保证了数据包的顺序传送及数据的完整性。该层定义了两个主要的协议:
- 传输控制协议 TCP(transmission control protocol)
- 用户数据报协议 UDP(user datagram protocol)
传输层对应OSI概念模型的传输层。传输层提供应用程序间的通信。其功能包括:
- 格式化信息流
- 提供可靠传输。
为实现后者,传输层协议规定接收端必须发回确认信息,如果分组丢失,必须重新发送。
应用层
TCP/IP概念模型中的应用层对应OSI的应用层、表示层和会话层,应用层协议主要包括:
- 邮局协议(Post Office Protocol,缩写:POP)
- 域名系统(Domain Name System,缩写:DNS)
- 文件传输协议(File Transfer Protocol,缩写:FTP)
- 超文本传输协议(HyperText Transfer Protocol,缩写:HTTP)
- 简单邮件传输协议 (Simple Mail Transfer Protocol,缩写:SMTP)
- 实时传输协议(Real-time Transport Protocol,缩写:RTP)
- 安全壳协议(Secure Shell,缩写:SSH)
- 传输层安全协议(Transport Layer Security,缩写:TLS)
- 安全套接层(Secure Sockets Layer,缩写:SSL)
应用层位于协议栈的顶端,它的主要任务是应用。一般是可见的,如利用FTP(文件传输协议)传输一个文件,请求一个和目标计算机的连接,在传输文件的过程中,用户和远程计算机交换的一部分是能看到的。
应用层是Linux网络设定最关键的一层。Linux服务器的配置文档主要针对应用层中的协议。
TCP和UPD
TCP 协议是面向连接的协议,类似于打电话,在开始传输数据之前,必须先建立明确的连接。
每一条TCP连接只能有两个端点,每一条TCP连接只能是点对点的, TCP提供全双工通信。数据在两个方向上独立的进行传输。因此,连接的每一端必须保持每个方向上的传输数据序号。
它将一台主机发出的字节流无差错地发往互联网上的其他主机。在发送端,它负责把上层传送下来的字节流分成报文段并传递给下层。在接收端,它负责把收到的报文进行重组后递交给上层。
面向字节流的含义:虽然应用程序和TCP交互是一次一个数据块,但TCP把应用程序交下来的数据仅仅是一连串的无结构的字节流。
面向连接的含义:面向连接是指两台主机在通讯的过程中,必须要先建立通讯关系,然后再去发送数据,也就是客户端首先向服务器发送数据,服务器给到客户端回应,具有通讯过程后再进行真正的数据传输。它是有两台固定的主机在通讯。
因此TCP协议是一个面向连接的、可靠的协议。它的可靠性表现在:
- 保证数据正确性
- 保证数据顺序
它的缺点在于:
- 传输速度慢
- 建立连接需要时间的系统资源较多
TCP协议还要处理端到端的流量控制,以避免缓慢接收的接收方没有足够的缓冲区接收发送方发送的大量数据。
TCP建立在IP之上,定义了网络上程序到程序的数据传输格式和规则,提供了IP数据包的传输确认、丢失数据包的重新请求、将收到的数据包按照它们的发送次序重新装配的机制。
UDP协议是一种面向非连接、不保证可靠的数据传输服务,主要适用于不需要对报文进行排序和流量控制的场合。 它的优点在于:
- 用于传输少量数据(数据包模式)
- 资源消耗小,处理速度快
UDP也建立在IP之上,但它是一种无连接协议,两台计算机之间的传输类似于传递邮件:消息从一台计算机发送到另一台计算机,两者之间没有明确的连接。
UDP不保证数据的传输,也不提供重新排列次序或重新请求的功能,所以说它是不可靠的。虽然UDP的不可靠性限制了它的应用场合,但它比TCP具有更好的传输效率,UDP的缺点在于:
- 不提供数据包分组、组装
- 不能对数据包进行排序
也就是说,当报文发送之后,是无法得知其是否安全完整到达的。在网络质量令人十分不满意的环境下,UDP协议数据包丢失会比较严重。但是由于UDP的特性:它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。比如我们聊天用的ICQ和QQ就是使用的UDP协议。
TCP和UDP的总结
TCP是一种流模式的协议,UDP是一种数据包模式的协议。
TCP是面向连接的,也就是说在连接持续的过程中,Socket中收到的数据都是由同一台主机发出的,因此只要保证数据是有序的到达就可以了,至于每次读取多少数据可以自己决定。
UDP是无连接的协议,也就是说,只要知道接收端的IP和端口,且网络是可达的,任何主机都可以向接收端发送数据。
UDP没有固定的主机,它在通讯之前不会测试这台主机是否存在,而直接发送数据。
TCP报文
TCP是一种面向连接连接导向的、可靠的基于字节流的传输层通信协议。TCP将用户数据打包成报文段,它发送后启动一个定时器,另一端收到的数据进行确认、对失序的数据重新排序、丢弃重复数据。
报文是网络中交换与传输的数据单元,即一次性要发送的数据块,包含了将要发送的完整的数据信息,会不断的封装成分组、包、帧来传输。TCP报文的格式如下:
固定首部长度为20字节,可变部分0~40字节,各字段解释:
- Source Port Number:源端口,范围0~65525。
- Target Port Number:目的端口,范围同上。
- Sequence Number:顺序号码,由发送方使用,TCP 连接中传送的数据流中的每一个字节都编上一个序号。序号字段的值则指的是本报文段所发送的数据的第一个字节的序号。
- Acknowledgement Number:确认序号,是接收数据方期望收到发送方的下一个报文段的序号,因此确认序号应当是上次已成功收到数据字节序号加1。
- Header Length:首部长度,它指出报文数据距TCP 报头的起始处有多远。一般首部长度为20字节。
- Reserved:保留字段(图中,包含CWR,ECE)保留今后使用,默认是0。
- URG:紧急比特,当 URG=1 时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快传送,相当于表示高优先级的数据。
- ACK:确认比特,只有当 ACK=1 时确认序号字段才有效。当 ACK=0 时,确认序号无效。
- PSH:推送比特,接收方 TCP 收到推送比特置1的报文段,就尽快地交付给接收应用进程,而不再等到整个缓存都填满了后再向上交付。
- RST:复位比特,当 RST=1 时,表明 TCP 连接中出现严重差错(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立运输连接。
- SYN:同步比特,在建立连接时用来同步序号。SYN=1, ACK=0表示一个连接请求报文段。SYN=1,ACK=1表示同意建立连接。
- FIN:终止比特,用来释放一个连接。当FIN=1 时,表明此报文段的发送端的数据已发送完毕,并要求释放运输连接。
- Window Size:窗口大小,16bits,窗口字段用来控制对方发送的数据量,单位为字节。TCP 连接的一端根据设置的缓存空间大小确定自己的接收窗口大小,然后通知对方以确定对方的发送窗口的上限。
- Checksum:检验和,16bits,该字段检验的范围包括首部和数据这两部分。在计算检验和时,要在 TCP 报文段的前面加上 12 字节的伪首部。由发端计算和存储,并由收端进行验证。
- Urgent Pointer:紧急指针字段,16bits,紧急指针指出在本报文段中的紧急数据的最后一个字节的序号。
- Options:选项字段,长度可变。用于把附加信息传递给终点,或用来对齐其它选项。 这部分最多包含40字节,因为TCP头部最长是60字节,其中还包含上面的20字节的固定部分。
Wireshark捕获到的TCP包报文下图所示:
TCP三次握手
TCP建立连接和断开连接的过程称为三次握手和四次挥手, 所谓三次握手(Three-way Handshake),是指客户端和服务器之间建立连接的过程。
如下图所示,Wireshark截获到了三次握手的三个数据包。第四个包才是HTTP的,说明HTTP的确是使用TCP建立连接的。
三次握手的流程图如下:
第一次握手:Client发送位码为 SYN = 1,随机产生 seq = x 的数据包到服务器,Server由 SYN = 1 知道Client要求建立连接;
第二次握手:Server收到请求后要确认连接信息,向Client发送ack number = x + 1(PS: Client的seq + 1),SYN = 1,ACK=1,随机产生 seq = y 的包;
第三次握手:Client收到后检查ack number是否正确,即第一次发送的 seq + 1,以及位码ACK是否为1,若正确,Client会再发送 ack number = y + 1 (PS: Sever的seq + 1),ACK = 1,Server收到后确认seq值与 ACK = 1 则连接建立成功。
完成三次握手,Client与Server开始传送数据。
下面使用Wireshark逐步分析三次握手过程:
第一次握手:客户端向服务器发送连接请求包,标志位SYN(同步序号)为1,序号为X=0
第二次握手:服务器收到客户端发过来报文,由SYN=1知道客户端要求建立联机。向客户端发送一个SYN和ACK都置为1的TCP报文,设置初始序号Y=0,将确认序号(Acknowledgement Number)设置为客户的序列号加1,即X+1 = 0+1=1, 如下图:
第三次握手:客户端收到服务器发来的包后检查确认序号(Acknowledgement Number)是否正确,即第一次发送的序号加1(X+1=1)。以及标志位ACK是否为1。若正确,服务器再次发送确认包,ACK标志位为1,SYN标志位为0。确认序号(Acknowledgement Number)=Y+1=0+1=1,发送序号为X+1=1。客户端收到后确认序号值与ACK=1则连接建立成功,可以传送数据了。
参考链接:
TCP介绍 - ZhangBinalan
iOS开发-Socket通信 - Eiwodetianna.
Linux服务器安全策略详解(第二版)- 曹江华